package cn.xiaopengstack.domain.strategy.service.rule.tree.engine.impl;

import cn.xiaopengstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import cn.xiaopengstack.domain.strategy.model.valobj.RuleTreeNodeLineVO;
import cn.xiaopengstack.domain.strategy.model.valobj.RuleTreeNodeVO;
import cn.xiaopengstack.domain.strategy.model.valobj.RuleTreeVO;
import cn.xiaopengstack.domain.strategy.service.rule.tree.ILogicTreeNode;
import cn.xiaopengstack.domain.strategy.service.rule.tree.engine.IDecisionTreeEngine;
import cn.xiaopengstack.domain.strategy.service.rule.tree.impl.DefaultTreeFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author jiangyangang
 */
@Slf4j
public class DecisionTreeEngine implements IDecisionTreeEngine {

    private final Map<String, ILogicTreeNode> logicTreeNodeGroup;

    private final RuleTreeVO ruleTreeVO;

    public DecisionTreeEngine(Map<String, ILogicTreeNode> logicTreeNodeGroup, RuleTreeVO ruleTreeVO) {
        this.logicTreeNodeGroup = logicTreeNodeGroup;
        this.ruleTreeVO = ruleTreeVO;
    }

    @Override
    public DefaultTreeFactory.StrategyAwardVO process(DefaultTreeFactory.TreeActionMatterEntity treeMatter) {
        // 获取下一个节点
        String nextNode = ruleTreeVO.getTreeRootRuleNode();
        Map<String, RuleTreeNodeVO> treeNodeMap = ruleTreeVO.getTreeNodeMap();

        assert StringUtils.isNoneEmpty(nextNode) && !CollectionUtils.isEmpty(treeNodeMap);

        // 获取起始节点「根节点记录了第一个要执行的规则」
        RuleTreeNodeVO ruleTreeNode = treeNodeMap.get(nextNode);

        DefaultTreeFactory.StrategyAwardVO strategyAwardVO = null;
        // 从根节点开始往下执行
        while (null != nextNode && Objects.nonNull(ruleTreeNode)) {
            // 获取决策节点
            ILogicTreeNode logicTreeNode = logicTreeNodeGroup.get(ruleTreeNode.getRuleKey());
            // 节点计算
            DefaultTreeFactory.TreeActionEntity logicExecuteEntity = logicTreeNode.logic(treeMatter);
            RuleLogicCheckTypeVO ruleLogicCheckType = logicExecuteEntity.getRuleLogicCheckType();
            // 获取计算结果
            strategyAwardVO = logicExecuteEntity.getStrategyAwardVo();

            // 获取下一个节点
            nextNode = logicTreeNode.getNextNode(ruleLogicCheckType.getCode(), ruleTreeNode.getTreeNodeLineVOList());
            log.info("规则引擎执行，正在执行规则【{}】结果 【{}】，下一个应该执行【{}}", ruleTreeNode.getRuleKey(), logicExecuteEntity.getRuleLogicCheckType(), nextNode);

            ruleTreeNode = treeNodeMap.get(nextNode);
        }

        return strategyAwardVO;
    }

//    /**
//     * 获取下一个节点
//     * @param matterValue
//     * @param treeNodeLineVOList
//     * @return
//     */
//    private String nextNode(String matterValue, List<RuleTreeNodeLineVO> treeNodeLineVOList) {
//        if (StringUtils.isEmpty(matterValue) || CollectionUtils.isEmpty(treeNodeLineVOList)) {
//            return null;
//        }
//        // 根据引用循环查找下一个可执行的节点
//        for (RuleTreeNodeLineVO nodeLine : treeNodeLineVOList) {
//            if (isDecisionNode(matterValue, nodeLine)) {
//                // 返回下一个节点
//                return nodeLine.getRuleNodeTo();
//            }
//        }
//
//        throw new RuntimeException("决策树引擎，nextNode 计算失败，未找到可执行节点！");
//    }
//
//    /**
//     * 判断是否是可以选中执行的节点
//     * @param matterValue 1000 通过 1001 接管，不通过
//     * @param nodeLine 当前节点的引用
//     * @return
//     */
//    private boolean isDecisionNode(String matterValue, RuleTreeNodeLineVO nodeLine) {
//        switch (nodeLine.getRuleLimitType()) {
//            case EQUAL:
//                return matterValue.equals(nodeLine.getRuleLimitValue().getCode());
//            // 以下规则暂时不需要实现
//            case GT:
//            case LT:
//            case GE:
//            case LE:
//            default:
//                return false;
//        }
//    }
}
